/*!
 * @file OpenFIREdisplay.h
 * @brief Macros for lightgun HUD display (primarily for SSD1306 OLED modules).
 *
 * @copyright That One Seong, 2024
 * @copyright GNU Lesser General Public License
 */

#ifndef _OPENFIREDISPLAY_H_
#define _OPENFIREDISPLAY_H_

#include <stdint.h>
#include <Adafruit_SSD1306.h>

#include "OpenFIREDefines.h"

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

class ExtDisplay {
public:
    /// @brief Attempt to start display using current pin numbers from SamcoPreferences
    /// @return success (true) or fail (false)
    bool Begin();

    /// @brief Cleanup and delete current OLED object
    /// @details This is needed to ensure the wire object is cleaned up
    void Stop();

    /// @brief Update top panel with either a string of 22 characters, or a combination of text prefix and a profile name
    /// @details Prefix should only have up to seven characters, to prevent the profile name being cutoff
    void TopPanelUpdate(const char *, const char * = nullptr);

    /// @brief Clear screen for different gun modes
    void ScreenModeChange(const int &screenMode, const bool &isAnalog = false);

    /// @brief Perform maintenance operations (WIP)
    /// @details For when values aren't being updated, but still want to change something on the screen
    /// (i.e. small text printouts when health/ammo empty)
    void IdleOps();

    /// @brief Draw seen points here
    /// @details Should ONLY be used in scenarios where the mouse isn't being updated, i.e. calibration.
    ///          Arguments here point to the original arrays of seen coords [4]
    void DrawVisibleIR(int *pointX, int *pointY);

    /// @brief Draw hotkey pause mode layout
    void PauseScreenShow(const int &currentProf, const char* name1, const char* name2, const char* name3, const char* name4);

    /// @brief Update simple pause mode list on screen
    void PauseListUpdate(const int &selection);

    /// @brief Update simple pause mode profiles list on screen
    void PauseProfileUpdate(const int &selection, const char* name1, const char* name2, const char* name3, const char* name4);

    /// @brief Print save status message
    void SaveScreen(const int &status);

    /// @brief Update main screen ammo glyphs
    void PrintAmmo(const uint &ammo);

    /// @brief Update main screen life glyphs
    void PrintLife(const uint &life);

    enum ScreenMode_e {
        Screen_None = -1,
        Screen_Init = 0,
        Screen_Normal,
        Screen_Pause,
        Screen_Profile,
        Screen_Saving,
        Screen_SaveSuccess,
        Screen_SaveError,
        Screen_Calibrating,
        Screen_IRTest,
        Screen_Docked,
        Screen_Mamehook_Single,
        Screen_Mamehook_Dual
    };

    enum ScreenPauseList_e {
        ScreenPause_Calibrate = 0,
        ScreenPause_ProfileSelect,
        ScreenPause_Save,
        ScreenPause_Rumble,
        ScreenPause_Solenoid,
        ScreenPause_EscapeKey
    };

    enum ScreenSerialInit_e {
        ScreenSerial_None = 0,
        ScreenSerial_Life,
        ScreenSerial_Ammo,
        ScreenSerial_Both
    };

    Adafruit_SSD1306 *display = nullptr;

    /// @brief Whether life updates are in lifebar or life glyphs form
    bool lifeBar = false;

    /// @brief Which layout we use for serial mode
    uint8_t serialDisplayType = 0;

    /// @brief Whether MiSTer mode is in use right now or not
    bool mister = false;

private:
    int screenState = Screen_None;

    bool ammoEmpty = false;
    bool lifeEmpty = false;

    uint currentAmmo;
    uint currentLife;

    #define OLED_IDLEUPD_INTERVAL 5000
    #define OLED_TEMPUPD_INTERVAL 750

    // timestamps for periodic tasks in IdleOps()
    unsigned long ammoTimestamp = 0;
    unsigned long lifeTimestamp = 0;
    unsigned long idleTimeStamp = 0;

    #ifdef USES_TEMP
        void ShowTemp();

        int currentTemp;
        unsigned long idleTempStamp = 0;
        bool showingTemp = false;
        // storage of temperature string
        char tempString[5];
    #endif // USES_TEMP

    #define NUMBER_GLYPH_WIDTH 21
    #define NUMBER_GLYPH_HEIGHT 36
    /// @brief Glyphs for common HUD elements
    static constexpr uint8_t numbers[10][108] = {
        {   // 0
            0x1f, 0xff, 0xc0, 0x3f, 0xff, 0xe0, 0x5f, 0xff, 0xd0, 0xe0, 0x00, 0x78, 0xe0, 0x00, 0xf8, 0xe0,
            0x00, 0xf8, 0xe0, 0x01, 0xb8, 0xe0, 0x01, 0xb8, 0xe0, 0x03, 0x38, 0xe0, 0x03, 0x38, 0xe0, 0x06,
            0x38, 0xe0, 0x06, 0x38, 0xe0, 0x0c, 0x38, 0xe0, 0x0c, 0x38, 0xe0, 0x18, 0x38, 0xe0, 0x18, 0x38,
            0xef, 0xff, 0xb8, 0x5f, 0xff, 0xd0, 0xef, 0xff, 0xb8, 0xe0, 0x60, 0x38, 0xe0, 0x60, 0x38, 0xe0,
            0xc0, 0x38, 0xe0, 0xc0, 0x38, 0xe1, 0x80, 0x38, 0xe1, 0x80, 0x38, 0xe3, 0x00, 0x38, 0xe3, 0x00,
            0x38, 0xe6, 0x00, 0x38, 0xe6, 0x00, 0x38, 0xec, 0x00, 0x38, 0xec, 0x00, 0x38, 0xf8, 0x00, 0x38,
            0xf8, 0x00, 0x38, 0x5f, 0xff, 0xd0, 0x3f, 0xff, 0xe0, 0x1f, 0xff, 0xc0
        },
        {   // 1
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00,
            0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00,
            0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38,
            0x00, 0x00, 0x38, 0x00, 0x00, 0x10, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00,
            0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00,
            0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38,
            0x00, 0x00, 0x38, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        },
        {   // 2
            0x1f, 0xff, 0xc0, 0x3f, 0xff, 0xe0, 0x1f, 0xff, 0xd0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00,
            0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00,
            0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38,
            0x0f, 0xff, 0xb8, 0x5f, 0xff, 0xd0, 0xef, 0xff, 0x80, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0,
            0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00,
            0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00,
            0xe0, 0x00, 0x00, 0x5f, 0xff, 0xc0, 0x3f, 0xff, 0xe0, 0x1f, 0xff, 0xc0
        },
        {   // 3
            0x1f, 0xff, 0xc0, 0x3f, 0xff, 0xe0, 0x1f, 0xff, 0xd0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00,
            0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00,
            0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38,
            0x0f, 0xff, 0xb8, 0x1f, 0xff, 0xd0, 0x0f, 0xff, 0xb8, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00,
            0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00,
            0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38,
            0x00, 0x00, 0x38, 0x1f, 0xff, 0xd0, 0x3f, 0xff, 0xe0, 0x1f, 0xff, 0xc0
        },
        {   // 4
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0,
            0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00,
            0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38,
            0xef, 0xff, 0xb8, 0x5f, 0xff, 0xd0, 0x0f, 0xff, 0xb8, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00,
            0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00,
            0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38,
            0x00, 0x00, 0x38, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        },
        {   // 5
            0x1f, 0xff, 0xc0, 0x3f, 0xff, 0xe0, 0x5f, 0xff, 0xc0, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0,
            0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00,
            0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00,
            0xef, 0xff, 0x80, 0x5f, 0xff, 0xd0, 0x0f, 0xff, 0xb8, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00,
            0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00,
            0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38,
            0x00, 0x00, 0x38, 0x1f, 0xff, 0xd0, 0x3f, 0xff, 0xe0, 0x1f, 0xff, 0xc0
        },
        {   // 6
            0x1f, 0xff, 0xc0, 0x3f, 0xff, 0xe0, 0x5f, 0xff, 0xc0, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0,
            0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00,
            0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00,
            0xef, 0xff, 0x80, 0x5f, 0xff, 0xd0, 0xef, 0xff, 0xb8, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0,
            0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00,
            0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38,
            0xe0, 0x00, 0x38, 0x5f, 0xff, 0xd0, 0x3f, 0xff, 0xe0, 0x1f, 0xff, 0xc0
        },
        {   // 7
            0x1f, 0xff, 0xc0, 0x3f, 0xff, 0xe0, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x40, 0x00, 0x00, 0xc0, 0x00,
            0x00, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06,
            0x00, 0x00, 0x06, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00,
            0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00,
            0xc0, 0x00, 0x00, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
            0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x18, 0x00, 0x00,
            0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        },
        {   // 8
            0x1f, 0xff, 0xc0, 0x3f, 0xff, 0xe0, 0x5f, 0xff, 0xd0, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0,
            0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00,
            0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38,
            0xef, 0xff, 0xb8, 0x5f, 0xff, 0xd0, 0xef, 0xff, 0xb8, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0,
            0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00,
            0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38,
            0xe0, 0x00, 0x38, 0x5f, 0xff, 0xd0, 0x3f, 0xff, 0xe0, 0x1f, 0xff, 0xc0
        },
        {   // 9
            0x1f, 0xff, 0xc0, 0x3f, 0xff, 0xe0, 0x5f, 0xff, 0xd0, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0,
            0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00,
            0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38, 0xe0, 0x00, 0x38,
            0xef, 0xff, 0xb8, 0x5f, 0xff, 0xd0, 0x0f, 0xff, 0xb8, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00,
            0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00,
            0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38,
            0x00, 0x00, 0x38, 0x1f, 0xff, 0xd0, 0x3f, 0xff, 0xe0, 0x1f, 0xff, 0xc0
        }
    };

    #define HEART_SMALL_WIDTH 12
    #define HEART_SMALL_HEIGHT 16
    static constexpr uint8_t lifeIcoSmall[] = {
        0xff, 0xf0, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x90, 0x90, 0xb9, 0xd0, 0xbf, 0xd0, 0xbf, 0xd0,
        0xbf, 0xd0, 0x9f, 0x90, 0x8f, 0x10, 0x86, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0xff, 0xf0
    };

    #define HEART_LARGE_WIDTH 16
    #define HEART_LARGE_HEIGHT 20
    static constexpr uint8_t lifeIcoLarge[] = {
        0xff, 0xff, 0xc0, 0x03, 0xbf, 0xfd, 0xa0, 0x05, 0xa0, 0x05, 0xa0, 0x05, 0xa4, 0x25, 0xae, 0x75, 
        0xaf, 0xf5, 0xaf, 0xf5, 0xaf, 0xf5, 0xa7, 0xe5, 0xa3, 0xc5, 0xa1, 0x85, 0xa0, 0x05, 0xa0, 0x05, 
        0xa0, 0x05, 0xbf, 0xfd, 0xc0, 0x03, 0xff, 0xff
    };

    #define LIFEBAR_BANNER_WIDTH 23
    #define LIFEBAR_BANNER_HEIGHT 9
    static constexpr uint8_t lifeBarBanner[] = {
        0xc1, 0xbf, 0x7e, 0xc1, 0xbf, 0x7e, 0xc1, 0xb8, 0x60, 0xc1, 0xb0, 0x60, 0xc1, 0xbe, 0x7c, 0xc1, 
        0xbe, 0x60, 0xc1, 0xb0, 0x60, 0xfd, 0xb0, 0x7e, 0xfd, 0xb0, 0x7e
    };

    #define LIFEBAR_SMALL_WIDTH 59
    #define LIFEBAR_SMALL_HEIGHT 9
    static constexpr uint8_t lifeBarSmall[] = {
        0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
        0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 
        0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 
        0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
        0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80
    };

    #define LIFEBAR_LARGE_WIDTH 106
    #define LIFEBAR_LARGE_HEIGHT 13
    static constexpr uint8_t lifeBarLarge[] = {
        0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x60, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x01, 0xc0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x01, 0xc0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 
        0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0xe0, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x60, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
        0xff, 0xff, 0xff, 0xff, 0xfe, 0x00
    };

    static constexpr uint8_t reloadGlyph[] = {
        // RELOAD
    };

    #define DIVIDER_WIDTH 1
    #define DIVIDER_HEIGHT 48
    // if only we could draw this vertically, sigh
    static constexpr uint8_t dividerLine[] = {
        0x40, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 
        0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 
        0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00
    };

    #define ARROW_WIDTH 9
    #define ARROW_HEIGHT 5
    static constexpr uint8_t upArrowGlyph[] = {
        0x08, 0x00, 0x14, 0x00, 0x22, 0x00, 0x41, 0x00, 0x80, 0x80
    };

    static constexpr uint8_t downArrowGlyph[] = {
        0x80, 0x80, 0x41, 0x00, 0x22, 0x00, 0x14, 0x00, 0x08, 0x00
    };

    #define CONNECTION_WIDTH 10
    #define CONNECTION_HEIGHT 17
    static constexpr uint8_t btConnectIco[] = {
        0x18, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x1b, 0x00, 0xd9, 0x80, 0x78, 0xc0, 0x39, 0x80, 0x1b, 0x00, 
        0x1e, 0x00, 0x1b, 0x00, 0x39, 0x80, 0x78, 0xc0, 0xd9, 0x80, 0x1b, 0x00, 0x1e, 0x00, 0x1c, 0x00, 
        0x18, 0x00
    };

    static constexpr uint8_t usbConnectIco[] = {
        0x3f, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x7f, 0x80, 0xc0, 0xc0, 0x88, 0x40, 0x9c, 0x40, 
        0x89, 0x40, 0xa9, 0x40, 0xaa, 0x40, 0xac, 0x40, 0x98, 0x40, 0x88, 0x40, 0x80, 0x40, 0xff, 0xc0, 
        0x7f, 0x80
    };

    #define GAMEPAD_WIDTH 18
    #define GAMEPAD_HEIGHT 12

    static constexpr uint8_t gamepadIco[] = {
        0x38, 0x07, 0x00, 0x7d, 0xef, 0x80, 0x42, 0x10, 0x80, 0x80, 0x00, 0x40, 0x91, 0x22, 0x40, 0xb8, 
        0x05, 0x40, 0x93, 0x32, 0x40, 0x84, 0xc8, 0x40, 0x84, 0xc8, 0x40, 0x87, 0x38, 0x40, 0x44, 0x08, 
        0x80, 0x38, 0x07, 0x00
    };

    #define MOUSE_WIDTH 16
    #define MOUSE_HEIGHT 13

    static constexpr uint8_t mouseIco[] = {
        0x06, 0x00, 0x09, 0x03, 0x10, 0x84, 0x7c, 0x48, 0x92, 0x48, 0x92, 0x30, 0x92, 0x00, 0xfe, 0x00, 
        0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x44, 0x00, 0x38, 0x00
    };

    #define MAMEHOOK_WIDTH 21
    #define MAMEHOOK_HEIGHT 16

    static constexpr uint8_t mamehookIco[] = {
        0x00, 0x02, 0x08, 0x00, 0x06, 0x18, 0x00, 0x0e, 0x38, 0x00, 0x1a, 0x68, 0x00, 0x32, 0xc8, 0x00, 
        0x63, 0x88, 0x00, 0xc3, 0x08, 0x01, 0x82, 0x08, 0x03, 0x00, 0x08, 0x06, 0x10, 0x08, 0x0c, 0x30, 
        0x88, 0x18, 0x71, 0x88, 0x30, 0xb3, 0x88, 0x61, 0x35, 0x88, 0xc2, 0x39, 0x88, 0xfc, 0x31, 0xf8
    };

    #define MISTERKUN_WIDTH 32
    #define MISTERKUN_HEIGHT 31

    static constexpr uint8_t misterIco[] = {
        0x00, 0x40, 0x02, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x01, 0x50, 0x0a, 0x80, 0x02, 0xa8, 0x15, 0x40, 
        0x05, 0xf7, 0xef, 0xa0, 0x08, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 
        0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x10, 0x04, 0x20, 0x08, 
        0x17, 0xff, 0xff, 0xe8, 0x14, 0x7a, 0x5e, 0x28, 0x34, 0x32, 0x4c, 0x2c, 0x44, 0x03, 0xc0, 0x22, 
        0x42, 0x06, 0x60, 0x42, 0x81, 0xf9, 0x9f, 0x81, 0x80, 0x10, 0x08, 0x01, 0x80, 0x09, 0x90, 0x01, 
        0x40, 0x16, 0x68, 0x02, 0x40, 0x11, 0x88, 0x02, 0x30, 0x00, 0x00, 0x0c, 0x10, 0x00, 0x00, 0x08, 
        0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x20, 0x03, 0xc0, 0x04, 0x40, 0x04, 0x20, 0x02, 
        0x40, 0x08, 0x10, 0x02, 0x20, 0x08, 0x10, 0x04, 0x1f, 0xf0, 0x0f, 0xf8
    };

    #define CUSTSPLASHBANN_WIDTH 80
    #define CUSTSPLASHBANN_HEIGHT 16
    static constexpr uint8_t customSplashBanner[] = {
        0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0xef, 0xf1, 0xff, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x03, 
        0xfe, 0xef, 0xf9, 0xff, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xfe, 0xef, 0xf9, 0xc0, 0x7a, 0xf0, 
        0x00, 0x00, 0x00, 0x03, 0x80, 0xee, 0x1d, 0xc0, 0x72, 0x73, 0xfc, 0x1f, 0x8f, 0xf3, 0x80, 0xee, 
        0x0d, 0xc0, 0xe2, 0x3b, 0xfe, 0x3f, 0xcf, 0xfb, 0xfe, 0xee, 0x1d, 0xff, 0xff, 0xfb, 0x8f, 0x78, 
        0xef, 0xfb, 0xfe, 0xef, 0xf9, 0xff, 0xe2, 0x3b, 0x87, 0x70, 0x6e, 0x7b, 0xfe, 0xef, 0xf9, 0xc0, 
        0x72, 0x73, 0x8f, 0x7f, 0xee, 0x3b, 0x80, 0xef, 0xe1, 0xc0, 0x7a, 0xf3, 0xfe, 0x70, 0x0e, 0x3b, 
        0x80, 0xee, 0xf1, 0xc0, 0x3f, 0xe3, 0xfc, 0x78, 0xee, 0x3b, 0x80, 0xee, 0x79, 0xff, 0x1f, 0xc3, 
        0x80, 0x3f, 0xce, 0x3b, 0x80, 0xee, 0x3d, 0xff, 0x07, 0x03, 0x80, 0x1f, 0x8e, 0x3b, 0x80, 0xee, 
        0x1d, 0xff, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };

    #define CUSTSPLASH_WIDTH  48
    #define CUSTSPLASH_HEIGHT 48
    static constexpr uint8_t customSplash[] = {
        0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 
        0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 
        0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xf8, 0x1f, 0xf0, 0x00, 0x00, 0x1f, 0xc0, 0x03, 0xf8, 0x00, 
        0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x7e, 0x07, 0xe0, 0x7e, 0x00, 0x00, 0xfc, 0x1f, 0xf8, 
        0x3f, 0x00, 0x00, 0xf8, 0x7f, 0xfe, 0x1f, 0x00, 0x01, 0xf0, 0xfc, 0x3f, 0x0f, 0x80, 0x01, 0xe1, 
        0xf0, 0x0f, 0x87, 0x80, 0x03, 0xe3, 0xe0, 0x07, 0xc7, 0xc0, 0x03, 0xc3, 0xc0, 0x03, 0x03, 0xc0, 
        0x07, 0xc7, 0x80, 0x00, 0x03, 0xe0, 0x07, 0x87, 0x80, 0x00, 0x01, 0xe0, 0x07, 0x8f, 0x00, 0x00, 
        0x01, 0xe0, 0x0f, 0x8f, 0x00, 0x00, 0x01, 0xf0, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 
        0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x7b, 0xff, 0xff, 0xff, 
        0xff, 0x0f, 0x7b, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x7b, 0xc0, 0x00, 0xf0, 0x0f, 0x0f, 0x7b, 0xc0, 
        0x00, 0xf0, 0x0f, 0x80, 0x03, 0xc0, 0x01, 0xf0, 0x07, 0x8f, 0x7b, 0xc0, 0x01, 0xe0, 0x07, 0x8f, 
        0x7b, 0xc0, 0x01, 0xe0, 0x07, 0xcf, 0x7b, 0xff, 0x83, 0xe0, 0x03, 0xcf, 0x7b, 0xff, 0x83, 0xc0, 
        0x03, 0xe0, 0x03, 0xff, 0x87, 0xc0, 0x01, 0xe0, 0x03, 0xc0, 0x07, 0x80, 0x01, 0xf0, 0x03, 0xc0, 
        0x0f, 0x80, 0x00, 0xf8, 0x03, 0xc0, 0x1f, 0x00, 0x00, 0x7c, 0x03, 0xc0, 0x3e, 0x00, 0x00, 0x7e, 
        0x03, 0xc0, 0x7e, 0x00, 0x00, 0x3f, 0x03, 0xc0, 0xfc, 0x00, 0x00, 0x1f, 0xc3, 0xc3, 0xf8, 0x00, 
        0x00, 0x07, 0xfb, 0xdf, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 
        0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 
        0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00
    };
};

#endif // _OPENFIREDISPLAY_H_
